MockMvc做接口测试

MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便, 最方便的是对于客户测试,不需要启动服务器即可测试我们的Rest Api。

SpringMVC编写Rest示例

Controller示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Controller
@RequestMapping(value = "/test")
public class TestWebController {

@ResponseBody
@RequestMapping(value = "/list", method = {RequestMethod.GET})
public List getMock(@RequestParam(name = "id", required = false, defaultValue = "l0") String id) {
return Arrays.asList("l1", "l2", "l3", id);
}

@ResponseBody
@RequestMapping(value = "/pust", method = {RequestMethod.POST})
public Object postMock(@RequestBody Object data) {
return ImmutableMap.<String, String>builder().put("data", JSON.toJSONString(data)).build();
}

@RequestMapping(value = "/view", method = {RequestMethod.GET})
public ModelAndView viewMock(){
return new ModelAndView("index");
}
}

MockMvc测试Rest示例

  1. MockMvc基础交互示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:context/spring-context.xml", "classpath:context/spring-mvc.xml"})
@WebAppConfiguration(value = "src/main/webapp")
public class TestController {

private MockMvc mockMvc;

@Autowired
private WebApplicationContext webApplicationContext;

@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}

@Test
public void test01() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/list")
.cookie(new Cookie("token", "F3AF5F1D14F534F677XF3A00E352C")) // 登录授权
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}
}
```
MockMvc可以对controller中的一次调用进行模拟;
1、mockMvc.perform执行一个请求;
2、MockMvcRequestBuilders.get(urlTemplate, urlMultiParams)构造一个请求
3、ResultActions.andExpect添加执行完成后的断言
4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表示执行完成后返回相应的结果。

执行结果:

``` bash
["l1","l2","l3","l0"]

交互信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
MockHttpServletRequest:
HTTP Method = GET
Request URI = /test/list
Parameters = {}
Headers = {Accept=[application/json;charset=UTF-8]}

Handler:
Type = com.simple.example.web.TestWebController
Method = public java.util.List com.simple.example.web.TestWebController.getMock(java.lang.String)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = ["l1","l2","l3","l0"]
Forwarded URL = null
Redirected URL = null
Cookies = []
  1. MockMvc请求参数示例
1
2
3
4
5
6
7
8
9
10
11
@Test
public void test02() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/test/list?id={id}", "模板参数")
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}

执行结果:

1
["l1","l2","l3","模板参数"]
  1. MockMvc测试Post示例
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void test() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/test/pust")
.contentType(MediaType.APPLICATION_JSON)
.content(JSON.toString(Arrays.asList("p1", "p2")))
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}

交互信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
MockHttpServletRequest:
HTTP Method = POST
Request URI = /test/pust
Parameters = {}
Headers = {Content-Type=[application/json], Accept=[application/json;charset=UTF-8]}

Handler:
Type = com.simple.example.web.TestWebController
Method = public java.lang.Object com.simple.example.web.TestWebController.postMock(java.lang.Object)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"data":"[\"p1\",\"p2\"]"}
Forwarded URL = null
Redirected URL = null
Cookies = []

执行结果:

1
{"data":"[\"p1\",\"p2\"]"}
  1. 测试视图页
1
2
3
4
5
6
7
8
9
10
@Test
public void test05() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/test/view"))
.andExpect(view().name("index")) //验证视图页面
.andExpect(model().hasNoErrors()) //验证页面没有错误
.andExpect(status().isOk()) //验证状态码
.andDo(print())
.andReturn();
System.out.println(mvcResult.getModelAndView().getViewName());
}

执行结果:

1
index

MockMvc深入学习